// 跨平台兼容的请求工具类
import { getBaseURL, getTimeout } from './envConfig'

class Request {
  constructor() {
    this.baseURL = getBaseURL()
    this.timeout = getTimeout()
    this.header = {
      'Content-Type': 'application/json'
    }
  }

  // 设置基础配置
  setConfig(config) {
    this.baseURL = config.baseURL || this.baseURL
    this.timeout = config.timeout || this.timeout
    this.header = { ...this.header, ...config.header }
  }

  // 获取token
  getToken() {
    try {
      return uni.getStorageSync('token') || ''
    } catch (e) {
      return ''
    }
  }

  // 设置token
  setToken(token) {
    try {
      uni.setStorageSync('token', token)
    } catch (e) {
      console.error('设置token失败:', e)
    }
  }

  // 清除token
  clearToken() {
    try {
      uni.removeStorageSync('token')
    } catch (e) {
      console.error('清除token失败:', e)
    }
  }

  // 请求拦截器
  requestInterceptor(config) {
    // 添加token
    const token = this.getToken()
    if (token) {
      config.header = {
        ...config.header,
        'Authorization': `Bearer ${token}`
      }
    }

    // 处理URL
    if (config.url && !config.url.startsWith('http')) {
      config.url = this.baseURL + config.url
    }

    // 处理超时
    if (!config.timeout) {
      config.timeout = this.timeout
    }

    return config
  }

  // 响应拦截器
  responseInterceptor(response) {
    const { statusCode, data } = response

    // 请求成功 - 包括204 No Content
    if (statusCode >= 200 && statusCode < 300) {
      // 对于204状态码，返回成功标识
      if (statusCode === 204) {
        return { success: true }
      }
      return data
    }

    // 处理401未授权
    if (statusCode === 401) {
      this.clearToken()
      uni.showToast({
        title: '登录已过期，请重新登录',
        icon: 'none'
      })
      
      // 跳转到登录页
      setTimeout(() => {
        uni.reLaunch({
          url: '/pages/login/index'
        })
      }, 1500)
      
      return Promise.reject(new Error('登录已过期'))
    }

    // 处理其他错误
    const errorMsg = data?.message || `请求失败: ${statusCode}`
    uni.showToast({
      title: errorMsg,
      icon: 'none'
    })

    return Promise.reject(new Error(errorMsg))
  }

  // 统一请求方法
  request(config) {
    return new Promise((resolve, reject) => {
      // 请求拦截
      const finalConfig = this.requestInterceptor(config)

      // 显示加载提示
      if (finalConfig.loading !== false) {
        uni.showLoading({
          title: '加载中...',
          mask: true
        })
      }

      // 发起请求
      uni.request({
        ...finalConfig,
        success: (response) => {
          try {
            const result = this.responseInterceptor(response)
            resolve(result)
          } catch (error) {
            reject(error)
          }
        },
        fail: (error) => {
          console.error('请求失败:', error)
          
          // 网络错误提示
          let errorMsg = '网络请求失败'
          if (error.errMsg) {
            if (error.errMsg.includes('timeout')) {
              errorMsg = '请求超时，请检查网络'
            } else if (error.errMsg.includes('fail')) {
              errorMsg = '网络连接失败，请检查网络设置'
            }
          }
          
          uni.showToast({
            title: errorMsg,
            icon: 'none'
          })
          
          reject(new Error(errorMsg))
        },
        complete: () => {
          // 隐藏加载提示
          if (finalConfig.loading !== false) {
            uni.hideLoading()
          }
        }
      })
    })
  }

  // GET请求
  get(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'GET',
      data,
      ...config
    })
  }

  // POST请求
  post(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'POST',
      data,
      ...config
    })
  }

  // PUT请求
  put(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'PUT',
      data,
      ...config
    })
  }

  // DELETE请求
  delete(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'DELETE',
      data,
      ...config
    })
  }

  // 文件上传（兼容多平台）
  upload(url, filePath, config = {}) {
    return new Promise((resolve, reject) => {
      // 显示上传进度
      if (config.showProgress !== false) {
        uni.showLoading({
          title: '上传中...',
          mask: true
        })
      }

      // 获取token
      const token = this.getToken()
      const header = {
        'Authorization': `Bearer ${token}`,
        ...config.header
      }

      // 发起上传
      uni.uploadFile({
        url: this.baseURL + url,
        filePath,
        name: 'file',
        header,
        formData: config.formData || {},
        success: (response) => {
          try {
            const data = JSON.parse(response.data)
            if (data.success !== false) {
              resolve(data)
            } else {
              reject(new Error(data.message || '上传失败'))
            }
          } catch (e) {
            reject(new Error('上传响应解析失败'))
          }
        },
        fail: (error) => {
          console.error('上传失败:', error)
          uni.showToast({
            title: '上传失败，请重试',
            icon: 'none'
          })
          reject(new Error('上传失败'))
        },
        complete: () => {
          if (config.showProgress !== false) {
            uni.hideLoading()
          }
        }
      })
    })
  }

  // 文件下载
  download(url, config = {}) {
    return new Promise((resolve, reject) => {
      // 显示下载进度
      if (config.showProgress !== false) {
        uni.showLoading({
          title: '下载中...',
          mask: true
        })
      }

      // 获取token
      const token = this.getToken()
      const header = {
        'Authorization': `Bearer ${token}`,
        ...config.header
      }

      // 发起下载
      uni.downloadFile({
        url: this.baseURL + url,
        header,
        success: (response) => {
          if (response.statusCode === 200) {
            resolve(response.tempFilePath)
          } else {
            reject(new Error('下载失败'))
          }
        },
        fail: (error) => {
          console.error('下载失败:', error)
          uni.showToast({
            title: '下载失败，请重试',
            icon: 'none'
          })
          reject(new Error('下载失败'))
        },
        complete: () => {
          if (config.showProgress !== false) {
            uni.hideLoading()
          }
        }
      })
    })
  }
}

// 创建实例
const request = new Request()

// 设置默认配置
request.setConfig({
  baseURL: 'http://admin-yzy-two.wudkmao.top/api/v1',
  timeout: 10000,
  header: {
    'Content-Type': 'application/json'
  }
})

export { request, Request }
export default request